home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * StringUtils.c
- *
- * General string manipulation functions
- *
- ****************************************************************************/
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
- #include <limits.h>
-
- #include "StringUtils.h"
- #include "Assertion.h"
-
- /*****************************************************************************
- *
- * UpperChar
- *
- *****************************************************************************/
- char UpperChar(char chr)
- {
- if ((chr >= 'a') && (chr <= 'z'))
- chr -= 'a' - 'A';
-
- return chr;
- }
-
- /*****************************************************************************
- *
- * C STRINGS
- *
- * Various strings for manipulating existing C strings as well as for
- * converting to Pascal style strings
- *
- *****************************************************************************/
- /*****************************************************************************
- *
- * CStringCompare
- *
- * Compares two C-style strings and returns the following with case sensitivity
- * as an option.
- *
- * -2 if either string pointer is nil
- * -1 if string 1 is less than string 2
- * 0 if the strings are equal
- * 1 if string 2 is greater than string 1
- *
- *****************************************************************************/
- short CStringCompare(const char *s1, const char *s2, Boolean caseSensitive)
- {
- long len, len1, len2;
- char chr1, chr2;
-
-
- if ((!s1) || (!s2)) // sanity check for nil pointers
- return -2;
-
- len1 = CStringLength(s1); // get lengths of each string
- len2 = CStringLength(s2);
- len = (len1 < len2) ? len1 : len2; // begin by only comparing common portions
-
- while(--len >= 0) // compare common portions
- { // if there is a difference return 1 or -1
- chr1 = *s1++; // get characters and move pointers
- chr2 = *s2++;
-
- if (!caseSensitive) // uppercase if need be
- {
- chr1 = UpperChar(chr1);
- chr2 = UpperChar(chr2);
- }
-
- if (chr1 > chr2)
- return 1;
- else if (chr1 < chr2)
- return -1;
- }
-
- if (len1 == len2) // common portions were identical, if lengths were
- return 0; // equal than strings are identical
- else if (len1 < len2) // otherwise if string 1 is shorter, than return
- return -1; // -1 (it's less than string 2) otherwise string 2
- else // is shorter and thus return (1).
- return 1;
- }
-
-
- /*****************************************************************************
- *
- * CStringConcat
- *
- * Concatenates two C-style strings.
- *
- * NOTE: It is assumed there is enough space at s1 to concat s2!
- *
- *****************************************************************************/
- void CStringConcat(char *s1, const char *s2)
- {
- if ((!s1) || (!s2)) // sanity check for nil pointers
- return;
-
- while (*s1) // move to the end of the first string
- s1++; // halt when we hit null char
-
- #pragma warn_possunwant off
-
- while (*s1++ = *s2++) // copy second string to first string
- ; // halt when we hit null char
-
- #pragma warn_possunwant reset
- }
-
-
-
- /*****************************************************************************
- *
- * CStringEqual
- *
- * Returns true if the two C-style strings are equal.
- *
- *****************************************************************************/
- Boolean CStringEqual(const char *s1, const char *s2, Boolean caseSensitive)
- {
- short len;
- char chr1, chr2;
-
-
- if ((!s1) || (!s2)) // sanity check for nil pointers
- return false;
-
- len = CStringLength(s1); // get length of first string
-
- if (len != CStringLength(s2)) // length of second string must equal first
- return false;
-
- while (--len >= 0) // check that every character in each string
- {
- chr1 = *s1++; // get characters and move pointers
- chr2 = *s2++;
-
- if (!caseSensitive) // uppercase if need be
- {
- chr1 = UpperChar(chr1);
- chr2 = UpperChar(chr2);
- }
-
- if (chr2 != chr1) // match--stop at first one that doesn't
- return false;
- }
-
- return true; // we have a match
- }
-
-
- /*****************************************************************************
- *
- * CStringLength
- *
- * Returns the length of a C-style string (null terminated)
- *
- *****************************************************************************/
- long CStringLength(const char *s)
- {
- long len;
-
- if (!s) // sanity check for nil pointer
- return 0;
-
- len = 0; // no characters yet
-
- while (*s++) // while current character is not nil,
- len++; // increment pointer and increment length
-
- return len; // return length
- }
-
-
- /*****************************************************************************
- *
- * CToPString
- *
- * Copies the specified C-style string to a Pascal-style string This
- * function can convert the string in place:
- *
- * CToPString(s, (StringPtr) s);
- *
- *****************************************************************************/
- void CToPString(const char *cs, StringPtr ps)
- {
- short len;
- char *t;
-
-
- if ((!cs) || (!ps)) // sanity check for nil pointers
- return;
-
- len = 0;
- t = (char *) cs;
-
- while (*t++) // find length by searching
- len++; // string for a null byte
-
- Assert(len <= 255, "STRING UTILS: String is too long to convert from C to Pascal without truncation.");
-
- if (len > 255)
- len = 255;
-
- if ((void *) cs == (void *) ps) // are we copying back to the same buffer?
- { // if so, just use BlockMoveData
- BlockMoveData(cs, ps+1, len);
- *ps = len;
- }
- else
- {
-
- *ps++ = len; // stuff in new length and step past it
-
- while (len-- >= 0) // copy each character over
- *ps++ = *cs++;
- }
- }
-
-
-
- /*****************************************************************************
- *
- * PStringConcat
- *
- * Concatenates two Pascal-style strings. If the concatenation would overflow
- * the maximum Pascal-style string (255 characters) it is halted at that point.
- *
- *****************************************************************************/
- void PStringConcat(StringPtr s1, StringPtr s2)
- {
- short len1, len2;
-
- if ((!s1) || (!s2)) // sanity check for nil pointers
- return;
-
- len1 = *s1;
- len2 = *s2;
-
- if ((len1 + len2) > 255) // ensure we don't overflow!
- len2 = (255 - len1);
-
- *s1 = len1 + len2; // stuff in new length
-
- *s1++; // skip length bytes
- *s2++;
-
- while (--len1 >= 0) // move to the end of the first string
- s1++;
-
- while (--len2 >= 0) // copy second string to first string
- *s1++ = *s2++;
- }
-
-
- /*****************************************************************************
- *
- * PStringCopy
- *
- * Copies the specified string to a duplicate string
- *
- *****************************************************************************/
- void PStringCopy(StringPtr original, StringPtr duplicate)
- {
- short len;
-
-
- if (!original) // if original is nil
- if (duplicate) // and duplicate exists
- { // set duplicate to a null string
- *duplicate = (char) 0;
- return;
- }
-
- len = (short) *original; // how many bytes to copy?
-
- if (duplicate) // ensure duplicate exists
- while (len-- >= 0) // for every byte + 1 (include length byte)
- *duplicate++ = *original++; // copy original contents over to duplicate
- }
-
- /*****************************************************************************
- *
- * PToCString
- *
- * Copies the specified Pascal-style string to a C-style string. This function
- * can convert the string in place:
- *
- * PToString(string, (char *) string);
- *
- *****************************************************************************/
- void PToCString(StringPtr ps, char *cs)
- {
- short len;
-
-
- if ((!cs) || (!ps)) // sanity check for nil pointers
- return;
-
- len = (short) *ps++; // get length and skip length byte
-
- while (len--) // while there is at least one more character...
- *cs++ = *ps++; // copy it and advance pointers
-
- *cs = (char) 0; // stick in a null byte
- }
-
- /*****************************************************************************
- *
- * TEXT BLOCKS
- *
- * Conversions between C- and Pascal-Style string to text, which is a contiguous
- * series of characters with neither a prefix length nor a trailing null character.
- * AppleEvents use this form of text to pass data around.
- *
- *****************************************************************************/
- /*****************************************************************************
- *
- * PStringToText
- *
- * Converts a Pascal-style string into a handle to a block of text.
- *
- ****************************************************************************/
- void PStringToText(const StringPtr pString, Handle textBlock)
- {
- long numBytes = (long)pString[0];
-
- if (GetHandleSize(textBlock) < numBytes)
- ReallocateHandle(textBlock, numBytes);
-
- BlockMoveData(pString+1, *textBlock, numBytes);
- }
-
-
- /*****************************************************************************
- *
- * CStringToText
- *
- * Converts a C-style string into a handle to a block of text.
- *
- ****************************************************************************/
- void CStringToText(const char *cString, Handle textBlock)
- {
- long numBytes = strlen(cString);
-
- if (GetHandleSize(textBlock) < numBytes)
- ReallocateHandle(textBlock, numBytes);
-
- BlockMoveData(cString, *textBlock, numBytes);
- }
-
-
- /*****************************************************************************
- *
- * TextToPString
- *
- * Converts a handle to a block of text into a Pascal-style string.
- *
- ****************************************************************************/
- void TextToPString(const Handle textBlock, StringPtr pString)
- {
- long numBytes = GetHandleSize(textBlock);
-
- if (numBytes > 255)
- numBytes = 255;
-
- pString[0] = (char)numBytes;
-
- BlockMoveData(*textBlock, pString+1, numBytes);
- }
-
-
- /*****************************************************************************
- *
- * TextToCString
- *
- * Converts a handle to a block of text into a C-style string.
- *
- ****************************************************************************/
- void TextToCString(const Handle textBlock, char *cString, Size maxLen)
- {
- long numBytes = GetHandleSize(textBlock);
-
- if (numBytes >= maxLen)
- numBytes = maxLen-1;
-
- BlockMoveData(*textBlock, cString, numBytes);
-
- cString[numBytes] = '\0';
- }
-
-
- /*****************************************************************************
- *
- * OSTypeToCString
- *
- * Converts a Macintosh OSType like 'cPar' to a c-style string like "cPar"
- *
- *****************************************************************************/
- void OSTypeToCString(OSType type, char *buffer)
- {
-
- short i = 0;
- OSType tempType = type;
-
- for (i = 0; i <= 3; i++)
- {
- buffer[3-i] = (char)(tempType & 0x000000FF);
- tempType = tempType >> 8;
- }
-
- buffer[4] = '\0';
- }
-
-
- /*****************************************************************************
- *
- * OSTypeToPString
- *
- * Converts a Macintosh OSType like 'cPar' to a Pascal-style string like "\pcPar"
- *
- *****************************************************************************/
- void OSTypeToPString(OSType theType, char *buffer)
- {
- buffer[0] = 0x04;
- BlockMoveData(&theType, &buffer[1], 4);
- }
-
-
-
-
- /*****************************************************************************
- *
- * VersionString
- *
- * Extracts the version number string from the specified 'vers' resource and
- * concats it onto the end of the specified string (Pascal-style). The short
- * version number string is extracted.
- *
- *****************************************************************************/
- OSErr VersionString(short rID, StringPtr version)
- {
- VersRecHndl versionH;
- OSErr error;
-
- error = resNotFound;
- versionH = (VersRecHndl) GetResource('vers', rID);
-
- if (versionH)
- {
- HLock((Handle) versionH);
- PStringConcat(version,(**versionH).shortVersion);
- HUnlock((Handle) versionH);
- ReleaseResource((Handle) versionH);
- error = noErr;
- }
- else
- PStringConcat(version,"\p<unknown>");
-
- return error;
- }
-
-
-
-
-
-
-
-
-
-